package Twitim::API::OAuth;

use strict;
use warnings;

use LWP::UserAgent;
use Data::Random qw(rand_chars);
use Net::OAuth;

$Net::OAuth::PROTOCOL_VERSION = Net::OAuth::PROTOCOL_VERSION_1_0A;
my $consumer_key    = 'H4QLcQKuWUO0H9DA5dIuw';
my $consumer_secret = '3EagGKrLbm8SnrCIG6QVo6GH0IdMEMX1I7HPmj4Z4';
my $ClientUA_name = 'Twitim';

sub new {
    my $this  = shift;
    my $class = ref($this) || $this;
    my $self  = {@_};

    return bless $self, $class;
}

sub make_http_request {
    my ( $self, $method, $url, $extra, $access_token, $access_secret ) = @_;
    $extra ||= {};

    my $request = Net::OAuth->request("protected resource")->new(
        consumer_key     => $consumer_key,
        consumer_secret  => $consumer_secret,
        request_url      => $url,
        request_method   => $method,
        signature_method => 'HMAC-SHA1',
        timestamp        => time,
        nonce => join( '', rand_chars( ssize => 16, set => 'alphanumeric' ) ),
        token => $access_token,
        token_secret => $access_secret,
        extra_params => $extra,
    );

    $request->sign;

    my $http_hdr = HTTP::Headers->new( 'User-Agent' => $ClientUA_name );
    my $post_body;

    if ( $method eq 'POST' ) {
        $post_body = $request->to_post_body;
    }
    else {
        $url = $request->to_url;
    }

    my $http_req = HTTP::Request->new( $method, $url, $http_hdr, $post_body );

    return $http_req;
}

sub open_authorize_url {
    my $request_method    = 'GET';
    my $request_token_url = 'http://twitter.com/oauth/request_token';
    my $authorize_url     = 'http://twitter.com/oauth/authorize';

    my $request = Net::OAuth->request("request token")->new(
        consumer_key     => $consumer_key,
        consumer_secret  => $consumer_secret,
        request_url      => $request_token_url,
        request_method   => $request_method,
        signature_method => 'HMAC-SHA1',
        timestamp        => time,
        nonce => join( '', rand_chars( ssize => 16, set => 'alphanumeric' ) ),
        callback => 'oob',
    );

    $request->sign;

    my $ua       = LWP::UserAgent->new;
    my $http_hdr = HTTP::Headers->new(
        'Authorization' => $request->to_authorization_header );
    my $http_req = HTTP::Request->new( $request_method, $request_token_url,
        $http_hdr );
    my $http_res = $ua->request($http_req);

    my $response = Net::OAuth->response('request token')
        ->from_post_body( $http_res->content );

    my $url = $authorize_url . "?" . $http_res->content;
    return ( $url, $response->token );
}

sub get_access_token {
    my ( $self, $token, $pin ) = @_;

    my $request_method   = 'POST';
    my $access_token_url = 'http://twitter.com/oauth/access_token';

    my $request = Net::OAuth->request("access token")->new(
        consumer_key     => $consumer_key,
        consumer_secret  => $consumer_secret,
        request_url      => $access_token_url,
        request_method   => $request_method,
        signature_method => 'HMAC-SHA1',
        timestamp        => time,
        nonce => join( '', rand_chars( ssize => 16, set => 'alphanumeric' ) ),
        callback     => '',
        token        => $token,
        verifier     => $pin,
        token_secret => '',
    );

    my $ua       = LWP::UserAgent->new;
    my $http_hdr = HTTP::Headers->new( 'User-Agent' => $ClientUA_name );
    my $http_req = HTTP::Request->new(
        $request_method, $access_token_url,
        $http_hdr,       $request->to_post_body
    );

    my $http_res = $ua->request($http_req);
    my $response = Net::OAuth->response('access token')
        ->from_post_body( $http_res->content );

    my %response;
    $response{'token'}        = $response->token;
    $response{'token_secret'} = $response->token_secret;
    ( $response{'user'} ) = $http_res->content =~ /screen_name=([^&]+)/;

    return %response;
}

1;
